/**
 * Alipay.com Inc.
 * Copyright (c) 2004-2022 All Rights Reserved.
 */
package com.example.spider.proxy.provider.local;

import cn.hutool.core.lang.Validator;
import com.example.spider.proxy.core.ProxyInfo;
import com.example.spider.proxy.core.tester.ProxyTypeEnum;
import com.example.spider.proxy.provider.AbstractProxyResultHandler;
import com.example.spider.proxy.provider.IpProxySpiderTask;
import com.example.spider.starter.SpiderStarter;
import com.example.spider.task.SpiderTaskQueue;
import com.example.spider.web.ProgressController;
import jakarta.annotation.Nonnull;
import org.shoulder.batch.progress.BatchProgress;
import org.shoulder.batch.progress.BatchProgressCache;
import org.shoulder.core.util.JsonUtils;
import org.shoulder.core.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.net.Proxy;
import java.time.Duration;
import java.util.Arrays;
import java.util.Objects;
import java.util.function.Function;

/**
 * file -> repository
 *
 * @author lym
 */
//@Component
public class LocalTextFileHandler extends AbstractProxyResultHandler implements SpiderStarter {

    @Autowired
    private BatchProgressCache progressCache;

    public LocalTextFileHandler() {
        super("txt");
    }

    protected Duration defaultLimitRateDuration() {
        return Duration.ofSeconds(5);
    }

    @Nonnull
    private static Function<String, ProxyInfo> jsonToProxyInfo() {
        return line -> JsonUtils.parseObject(line, ProxyInfo.class);
    }

    @Nonnull
    private static Function<String, ProxyInfo> ipPortToProxyInfo() {
        return line -> JsonUtils.parseObject(line, ProxyInfo.class);
    }

    @Nonnull
    private static Function<String, ProxyInfo> csvToProxyInfo() {
        // IP;PORT;COUNTRY;RELIABILITY
        return line -> {

            String[] parts = line.split(";");
            if (Validator.isNumber(parts[1]) && Validator.isNumber(parts[3].replace("%", "").trim())) {
                int accessablePercentage = Integer.parseInt(parts[3].replace("%", "").trim());
                if (accessablePercentage > 5) {
                    return null;
                }
                return ProxyInfo.builder()
                        .ip(parts[0])
                        .port(Integer.parseInt(parts[1]))
                        .source("mega")
                        .location(parts[2])
                        .successPercentage(Integer.parseInt(parts[3].replace("%", "").trim()))
                        .build();
            }
            return null;

        };
    }

    private void readFileToSourceRepository(String filePath) {
        IpProxySpiderTask task = createTask("https://www.abc.com")
                .setIpProxyTaskId(taskName)
                .setIdempotentFilePath(filePath);
        SpiderTaskQueue.putTask(task);
    }

    /**
     * 每 10 分钟触发一次
     */
    @Override
    public String executeCron() {
        return null;
    }

    @Override
    public void startSpiders() {
        //addProxy(TaskContextProxyProvider.p1);
//        readFileToSourceRepository("F:\\spider\\ipProxy\\sourceProxyInfo.txt");
//        readFileToSourceRepository("E:\\downloads\\megaproxylist.csv");
    }

    private void addProxy(Proxy p) {
        sourceRepository.add(ProxyInfo.builder()
                .ip(p.address().toString().split(":")[0].replace("/", ""))
                .port(Integer.parseInt(p.address().toString().split(":")[1]))
                .type(p.type())
                .proxyTypeEnum(ProxyTypeEnum.of(p.type().name()))
                .source("local")
                .build());
    }

    /**
     * 处理响应
     */
    @Override
    public void doHandle(IpProxySpiderTask task, String textFile) {
        BatchProgress progress = new BatchProgress();
        String[] proxyStrArr = textFile.split("\\n");

        progress.setId("redisToSourceRepo_" + task.getIdempotentFilePath().replace(":", "_").replace("\\", "_").replace("/", ""));
        progress.setTotal(proxyStrArr.length);
        progress.start();
        progressCache.triggerFlushProgress(progress);
        log.warn("local -> repo 开始同步，进度： {} ", ProgressController.getProgressUrl(progress.getId()));

        Arrays.stream(proxyStrArr)
                .parallel()
                .map(jsonToProxyInfo())
                .filter(Objects::nonNull)
                .peek(p -> {
                    p.setSource(StringUtils.isBlank(p.getSource()) ? "local" : p.getSource());
//                    p.setProxyTypeEnum(ProxyTypeEnum.of(p.getType().name()));
                })
                .peek(super::addProxyToSourceRepository)
                .forEach(p -> progress.addSuccess(1));
        progress.finish();

        log.info("read from file [{}], total={} cost={}.", task.getIdempotentFilePath(), progress.getTotal(), Duration.between(progress.getStartTime(), progress.getStopTime()));
    }
}